package api

import (
	"gitee.com/liuxiaowei123/vblog-01/vblog-01/vblog/ioc"
	"gitee.com/liuxiaowei123/vblog-01/vblog-01/vblog/response"
	"gitee.com/liuxiaowei123/vblog-01/vblog-01/vblog/token"
	"github.com/gin-gonic/gin"
)

// 此文件通过restful风格的API 来暴漏token模块中的功能(login、logout)，通过Gin框架来处理http数据

// 定义api handler
type TokenApiHandler struct {
	ts token.Service
}

// 注册到ioc
func init() {
	ioc.ApiHandler().Registry(&TokenApiHandler{})
}

// 实现对象的初始化,也就是实例化
func (t *TokenApiHandler) Init() {
	t.ts = ioc.Controller().Get(token.Appname).(token.Service)
}

func (t *TokenApiHandler) Name() string {
	// 为什么要用token.Appname？
	// 因为是token模块中的api handler
	return token.Appname
}

// func NewTokenApiHandler() *TokenApiHandler {
// 	return &TokenApiHandler{
// 		ts: ioc.Controller().Get(token.Appname).(token.Service),
// 	}
// }

// 把handler注册到路由上
// 注意区分(r gin.IRouter)和(c *gin.Context)的指针写法
func (t *TokenApiHandler) Registry(r gin.IRouter) {
	// r 是Gin的路由
	// r.POST("/tokens/", t.Login)
	// r.DELETE("/tokens/", t.Logout)
	// 接口改进
	v1 := r.Group("v1")
	v1.POST("/tokens/", t.Login)
	v1.DELETE("/tokens/", t.Logout)
}

// 定义HandlerFunc，处理Login请求
func (t *TokenApiHandler) Login(c *gin.Context) {
	// 1.获取用户请求参数
	tklr := token.NewLoginRequest()
	// c.BindJSON(tklr) 来表示映射关系：把http body中的数据，映射到LoginRequest对象中
	err := c.BindJSON(tklr)
	if err != nil {
		// c.JSON就会返回http code和response
		// c.JSON(http.StatusBadRequest, err)
		// 改进
		response.Failed(c, err)
		// 如果不写return，报错后不会中断
		return
	}

	// 2.处理请求
	// 执行这个操作时，需要依赖token模块中login
	// c.Request.Context()表示来自http请求的context
	tk, err := t.ts.Login(c.Request.Context(), tklr)
	if err != nil {
		// c.JSON(http.StatusBadRequest, err)
		// 改进
		response.Failed(c, err)
		return
	}

	// 2.1.向客户端写入cookie(此段代码是在做 Api服务认证时，添加的)
	// 通过SetCookie把cookie直接写到浏览器客户端(Web)
	// SetCookie中的参数(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool)
	c.SetCookie(token.TOKEN_COOKIE_NAME, tk.AccessToken, 0, "/", "localhost", false, true)

	// 3.返回响应
	// c.JSON(http.StatusOK, tk)
	// 改进
	response.Success(c, tk)
}

// 处理logout HandlerFunc
func (t *TokenApiHandler) Logout(c *gin.Context) {}
